package com.note.common.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * JWT工具类
 * 用于生成、解析和验证JWT令牌
 */
@Slf4j
@Component
public class JwtUtils {

    /**
     * 用户ID在JWT中的声明名称
     */
    private static final String CLAIM_USER_ID = "userId";
    
    /**
     * 用户名在JWT中的声明名称
     */
    private static final String CLAIM_USERNAME = "username";

    /**
     * JWT密钥
     */
    @Value("${jwt.secret:noteSecretKey}")
    private String secret;

    /**
     * JWT过期时间（秒）
     */
    @Value("${jwt.expiration:86400}")
    private long expiration;

    /**
     * 生成JWT令牌
     *
     * @param userId 用户ID
     * @param username 用户名
     * @return JWT令牌
     */
    public String generateToken(Long userId, String username) {
        try {
            // 过期时间
            Date expirationDate = new Date(System.currentTimeMillis() + expiration * 1000);
            
            // 头部信息
            Map<String, Object> header = new HashMap<>();
            header.put("alg", "HS256");
            header.put("typ", "JWT");
            
            // 创建JWT
            return JWT.create()
                    .withHeader(header)
                    .withClaim(CLAIM_USER_ID, userId)
                    .withClaim(CLAIM_USERNAME, username)
                    .withIssuedAt(new Date())
                    .withExpiresAt(expirationDate)
                    .sign(Algorithm.HMAC256(secret));
        } catch (Exception e) {
            log.error("生成JWT令牌异常: userId={}, username={}, error={}", userId, username, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 从JWT令牌中获取用户ID
     *
     * @param token JWT令牌
     * @return 用户ID
     */
    public Long getUserIdFromToken(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim(CLAIM_USER_ID).asLong();
        } catch (Exception e) {
            log.error("从JWT令牌中获取用户ID异常: token={}, error={}", token, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 从JWT令牌中获取用户名
     *
     * @param token JWT令牌
     * @return 用户名
     */
    public String getUsernameFromToken(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim(CLAIM_USERNAME).asString();
        } catch (Exception e) {
            log.error("从JWT令牌中获取用户名异常: token={}, error={}", token, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 验证JWT令牌
     *
     * @param token JWT令牌
     * @return 是否有效
     */
    public boolean validateToken(String token) {
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret)).build();
            verifier.verify(token);
            return true;
        } catch (JWTVerificationException e) {
            log.error("JWT令牌验证失败: token={}, error={}", token, e.getMessage());
            return false;
        } catch (Exception e) {
            log.error("JWT令牌验证异常: token={}, error={}", token, e.getMessage(), e);
            return false;
        }
    }
} 